package graph.tests;

import graph.*;
import java.util.*;

public class MockGraph implements IGraph{

    private int indexCurrentVertex;

    public final static String A = "A";
    public final static String B = "B";
    public final static String C = "C";
    public final static String D = "D";
    public final static String E = "E";

    private final static String AB = "AB";
    private final static String BC = "BC";
    private final static String CD = "CD";
    private final static String DC = "DC";
    private final static String DE = "DE";
    private final static String AD = "AD";
    private final static String CE = "CE";
    private final static String EB = "EB";
    private final static String AE = "AE";

    private final static int VERTICES_NUMBER = 5;

    private ArrayList pathsList;

    public MockGraph() {
        pathsList = new ArrayList();
        indexCurrentVertex = 0;
    }

    public void buildGraphTest() {
        addVertex(A);
        addVertex(B);
        addVertex(C);
        addVertex(D);
        addVertex(E);
        addEdge(A, B, 5);
        addEdge(B, C, 4);
        addEdge(C, D, 8);
        addEdge(D, C, 8);
        addEdge(D, E, 6);
        addEdge(A, D, 5);
        addEdge(C, E, 2);
        addEdge(E, B, 3);
        addEdge(A, E, 7);
    }

    public int getVerticesNumber(){
        return VERTICES_NUMBER;
    }

    public void addVertex(Object vertex){
        if ( indexCurrentVertex >= VERTICES_NUMBER) {
            // Maybe I should throw another exception because it is not the argument which is illegal ...
            throw new IllegalArgumentException("Can't add the vertex because all the vertices have been alreay added");
        }
        indexCurrentVertex++;
    }

    public void addEdge(Object startVertex, Object destinationVertex, int weight){
        if (!vertexExist(startVertex) || !vertexExist(destinationVertex) ) {
            throw new IllegalArgumentException("The  vertex(ices) do not exist in the graph.");
        }

        if (weight <= 0) {
            throw new IllegalArgumentException("Invalid weight ! " + weight + ". Must be > 0");
        }
        pathsList.add(startVertex.toString() + destinationVertex.toString());
    }

    public void removeEdge(Object startVertex, Object destinationVertex) {
        pathsList.remove(startVertex.toString() + destinationVertex.toString());
    }

    public boolean edgeExist(Object startVertex, Object destinationVertex){
        if (pathsList.contains( startVertex.toString() + destinationVertex.toString() )) {
            return true;
        }
        else {
            return false;
        }
    }

    public boolean vertexExist(Object vertex){
        if ( vertex.equals(A) || vertex.equals(B) || vertex.equals(C) || vertex.equals(D) || vertex.equals(E)) {
            return true;
        }
        else {
            return false;
        }
    }

    public int getEdgeWeight(Object startVertex, Object destinationVertex){
        if ( edgeExist(startVertex, destinationVertex) ) {
            String path = startVertex.toString() + destinationVertex.toString();
            if (path.equals(AB))
                return 5;
            if (path.equals(BC))
                return 4;
            if (path.equals(CD))
                return 8;
            if (path.equals(DC))
                return 8;
            if (path.equals(DE))
                return 6;
            if (path.equals(AD))
                return 5;
            if (path.equals(CE))
                return 2;
            if (path.equals(EB))
                return 3;
            if (path.equals(AE))
                return 7;
            // default !
            return 0;
        }
        else {
            return 0;
        }
    }

    public int getEdgeWeight(Path verticesList) {
        // for the question 9
        if ("B-C-E-B".equals(verticesList.toString()) )
            return 9;

        if ("A-B-C".equals(verticesList.toString()) )
            return 9;

        if ("A-D".equals(verticesList.toString()) )
            return 5;

        if ("A-D-C".equals(verticesList.toString()) )
            return 13;

        if ( "A-E-B-C-D".equals(verticesList.toString()) )
            return 22;

        if ( "A-E-D".equals(verticesList.toString()) )
            return 0;

        return 0;
    }

    // this method gave wrong results if removeEdge has been called
    public Iterator getAdjacentVertices(Object vertex) {
        ArrayList adjacentVertices = new ArrayList();
        if (vertex.equals(A)) {
            adjacentVertices.add(B);
            adjacentVertices.add(D);
            adjacentVertices.add(E);
        }
        if (vertex.equals(B)) {
            adjacentVertices.add(C);
        }
        if (vertex.equals(C)) {
            adjacentVertices.add(D);
            adjacentVertices.add(E);
        }
        if (vertex.equals(D)) {
            adjacentVertices.add(C);
            adjacentVertices.add(E);
        }
        if (vertex.equals(E)) {
            adjacentVertices.add(B);
        }
        return adjacentVertices.iterator();
    }

    public Iterator getPredecessors(Object vertex) {
        ArrayList adjacentVertices = new ArrayList();
        if (vertex.equals(A)) {

        }
        if (vertex.equals(B)) {
            adjacentVertices.add(A);
            adjacentVertices.add(E);
        }
        if (vertex.equals(C)) {
            adjacentVertices.add(B);
            adjacentVertices.add(D);
        }
        if (vertex.equals(D)) {
            adjacentVertices.add(A);
            adjacentVertices.add(C);
        }
        if (vertex.equals(E)) {
            adjacentVertices.add(A);
            adjacentVertices.add(C);
            adjacentVertices.add(D);
        }
        return adjacentVertices.iterator();
    }
}
